import { defineComponent, PropType, ref, Ref, toRefs, computed } from "vue";
import styles from './HTMLRender.module.less'
import {
  width,
  height,
  transformScale,
  wapperWidth,
  verticalpadding,
  wapperHeight,
  getExposeConfig,
} from "./HTMLRender.helpers";
import { usePageState } from "./hooks";

const CommonStyle = {
  width: width + 'px',
  height: height + 'px',
}

export interface HTMLRenderProps {
  html: string;
}

export interface HTMLRenderExposed {
  exportPDF(): void;
  exportMd(): void;
  exportImage(): void;
  generateCover(coverName: string): Promise<File>
}

const htmlRenderProps = {
  html: {
    type: String as PropType<HTMLRenderProps['html']>,
    default: ''
  },
}
// HTML渲染器
export const HTMLRender = defineComponent({
  props: htmlRenderProps,
  setup(props, { expose }) {

    const { html } = toRefs(props)

    const {
      viewRef,
      wapperHeightRef,
      pageInfosRef
    } = usePageState(html)

    const pageInfoDomArry: HTMLDivElement[] = []


    expose(getExposeConfig(pageInfoDomArry));

    return () => {

      const htmlRenderWapperStyle = {
        width: wapperWidth + 'px',
        height: wapperHeightRef.value + 'px'
      }

      pageInfoDomArry.splice(0)

      const pageInfoChildren = pageInfosRef.value.map(({ top, height }, index) => {

        const collectRef = (exposed: PageInfoPropsExposed | undefined) => {
          if (exposed && exposed.value) {
            pageInfoDomArry.push(exposed.value)
          }
        }

        return (
          <>
            {index !== 0 && (<div class={styles.divider} />)}
            <PageInfo
              height={height}
              top={top}
              html={html.value}
              ref={collectRef as any}
            />
          </>
        )
      })

      return (
        <div class={styles.htmlRenderWapper} style={htmlRenderWapperStyle}>
          <div
            class={styles.htmlRender}
            style={{
              width: CommonStyle.width,
            }}
          >
            <div
              ref={viewRef}
              v-html={html.value}
              style={{ width: CommonStyle.width }}
              class={styles.calcResumeTemplate}
            />
            {pageInfoChildren}
          </div>
        </div>
      )
    };
  },
});


type PageInfoPropsExposed = Ref<HTMLDivElement>

interface PageInfoProps {
  html: string;
  height: number;
  top: number;
}

const PageInfo = defineComponent({
  props: {
    html: {
      type: String as PropType<PageInfoProps['html']>,
      default: ''
    },
    top: {
      type: Number as PropType<PageInfoProps['top']>,
      default: 0
    },
    height: {
      type: Number as PropType<PageInfoProps['height']>,
      default: 0
    }
  },
  setup(props, { expose }) {
    const { html, top, height } = toRefs(props)

    const domRef = ref<HTMLDivElement>()

    expose(domRef as PageInfoPropsExposed)

    return () => (
      <div
        ref={domRef}
        class={styles.resumePageWrapper}
        style={{
          height: wapperHeight + 'px',
          width: wapperWidth + 'px',
          padding: `${verticalpadding}px 0`
        }}
      >
        <div
          style={{
            width: CommonStyle.width,
            height: height.value + 'px',
            transform: `scale(${transformScale})`,
          }}
          class={styles.resumePage}
        >
          <div
            style={{
              width: CommonStyle.width,
              top: -top.value + 'px',
              height: top.value + height.value + 'px'
            }}
            class={styles.resumeTemplate}
            v-html={html.value}
          />
        </div>
        <div
          class={styles.mask}
          style={{
            height: wapperHeight - verticalpadding - height.value * transformScale + 'px',
          }}
        />
      </div>
    )
  }
})

